package com.szsanshan.station.datacollector.schedule;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.szsanshan.station.datacollector.entity.*;
import com.szsanshan.station.datacollector.mapper.FuelposMapper;
import com.szsanshan.station.datacollector.service.PetrolDataService;
import com.szsanshan.station.datacollector.util.Constants;
import com.szsanshan.station.datacollector.util.HttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


/**
 * 描述：油罐状态定时器类
 */
@Component
public class PosScheduleJobs {

    private static String lastId = "-1";
    private final Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private FuelposMapper fuelposMapper;
    @Value("${controltype}")
    private String controlType;
    @Value("${control.url}")
    private String controlUrl;
    @Value("${control.http.port}")
    private int httpPort;
    @Resource
    private PetrolDataService petrolDataService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Scheduled(fixedRate = (2 * 1000))
    public void sendData() {
        if (!lastId.equals("-1")) {
            if (ControlType.BEILIN.getCode().equals(controlType)) {
                beiLinControlJob();
            } else if (ControlType.REDIS.getCode().equals(controlType)) {
                redisControlJob();
            }
        } else {
            lastId = petrolDataService.latestFuelRecordId();
        }
    }


    /**
     * 贝林中控数据和油枪状态发送
     */
    private void beiLinControlJob() {
        List<Fuelpos> list = fuelposMapper.findAll();
        List<StationNozzleRecord> sList = new ArrayList<>();
        for (Fuelpos f : list) {
            StationNozzleRecord record = new StationNozzleRecord();
            record.setNozno(f.getNozzleno().toString());
            record.setNozqty(f.getQty().toString());
            record.setNozmny(f.getActualmoney().toString());
            record.setNozprice(f.getActualprice().toString());
            record.setId(f.getId());
            record.setBegintime(f.getRecetime());
            record.setEndtime(f.getWorktime());
            record.setOilshortname(f.getOilsort());
            record.setNoztotalend(f.getNoztotalend());
            record.setJiayouyuan(f.getJiayouyuan());
            if (record.getEndtime() != null) {
                sList.add(record);
            }
        }
        if (sList.size() > 0) {
            boolean sent = petrolDataService.sendFuelRecords(sList);
            if (sent && sList.size() > 0) {
                for (Fuelpos f : list) {
                    fuelposMapper.update(f.getId());
                }
                lastId = sList.get(0).getId();
            }
        }
        List<StationNozzleStatus> statusList = fuelposMapper.getNozzleStatus();
        List<StationNozzleStatus> statusList2 = new ArrayList<>();
        for (StationNozzleStatus bo : statusList) {
            if ("1".equals(bo.getIstake())) {
                statusList2.add(bo);
            }
        }
        if (statusList2.size() > 0) {
            petrolDataService.sendStatusRecords(statusList2);
        }
    }

    /**
     * 发送油机状态数据
     */
    private void sendRedisStatusData() {
//      空闲：	{"gunNo":2,"ttc":454,"port":9401,"refuelMode":0,"cmd":"idle"}
//      加油中：	{"gunNo":1,"gsPrice":36.48,"port":9401,"gasAmount":7.37,"cmd":"fueling"}
//      加油记录：{"gunNo":1,"sumPrice":55418.67,"gsPrice":639.44,"isLastFlow":false,"boardInvoice":1,"ttc":478,"salePrice":4.95,
//                "port":9401,"sumGasAmount":10047.36,"gasAmount":129.18,"icNum":"0000000000000000","cmd":"finished","time":"2021-07-30 10:47:44"}
        List<StationNozzleStatus> statusList = new ArrayList<>();
        List<StationNozzleStatus> statusList2 = new ArrayList<>();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("cmd", "getGunNoStatus");
        String url = "http://" + controlUrl + ":" + httpPort + "/gunInfo/getGunNoStatus";
        String result = HttpUtils.httpRequest(url, "POST", jsonObject.toJSONString(), Constants.JSONTYPE);
        if (result.contains(Constants.SUCCESS)) {
            JSONObject jsonObject1 = JSON.parseObject(result);
            if (jsonObject1.getString(Constants.SUCCESS).equals("true")) {
                if (jsonObject1.getJSONObject("data").containsKey("gunStatus")) {
                    String statusData = jsonObject1.getJSONObject("data").getString("gunStatus");
                    List<RedisTrade> list = JSON.parseArray(statusData, RedisTrade.class);
                    for (RedisTrade redisTrade : list) {
                        StationNozzleStatus snr = new StationNozzleStatus();
                        String gunNo = redisTrade.getGunNo();
                        if (StringUtils.hasText(gunNo)) {
                            snr.setGunno(gunNo);
                            snr.setIstake(redisTrade.getCmd().equals("fueling") ? "1" : "0");
                            snr.setCurrnum(redisTrade.getGasAmount());
                            snr.setCurramount(redisTrade.getGsPrice());
                            statusList.add(snr);
                        }
                    }
                }
            }
        } else {
            logger.warn("@sendRedisStatusData#url={},param={},http-res={}", url, jsonObject, result);
        }
        for (StationNozzleStatus bo : statusList) {
            if ("1".equals(bo.getIstake())) {
                statusList2.add(bo);
            }
        }
        if (statusList2.size() > 0) {
            petrolDataService.sendStatusRecords(statusList2);
        }
    }

    /**
     * redis中控发送数据和状态
     */
    private void redisControlJob() {
        long min = Long.parseLong(lastId);
        List<StationNozzleRecord> recordList = fuelposMapper.findRedisTrade(min, min + 30);
        if (recordList.size() > 0) {
            boolean sent = petrolDataService.sendFuelRecords(recordList);
            if (sent) {
                lastId = recordList.get(0).getId();
                String sendIds = recordList.stream().map(StationNozzleRecord::getId).collect(Collectors.joining(","));
                logger.info("sent:{}", sendIds);
            }
        }
        sendRedisStatusData();
    }

    @Scheduled(fixedDelay = (1000))
    public void sendShiftToMachine() {
        if (ControlType.REDIS.getCode().equals(controlType)) {
            if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(Constants.TO_SHIFT))) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("cmd", "changeShift");
                HashMap<String, String> map = new HashMap<>();
                String time = stringRedisTemplate.opsForValue().get(Constants.TO_SHIFT);
                map.put("endTime", time);
                jsonObject.put("data", map);
                String url = "http://" + controlUrl + ":" + httpPort + "/shift/changeShift";
                logger.info("changeShift:out:" + jsonObject.toJSONString());
                String result = HttpUtils.httpRequest(url, "POST", jsonObject.toJSONString(), Constants.JSONTYPE);
                logger.info("changeShift:return:" + result);
                if (result.contains(Constants.SUCCESS)) {
                    assert time != null;
                    stringRedisTemplate.opsForValue().set(Constants.TO_SEND_SHIFT_DONE, time, 8L, TimeUnit.HOURS);
                    stringRedisTemplate.delete(Constants.TO_SHIFT);
                }
            }
        }
    }

    /**
     * 获取待交班时间
     */
    @Scheduled(fixedDelay = 3000)
    public void getToShiftTime() {
        if (ControlType.REDIS.getCode().equals(controlType)) {
            String toShiftTime = petrolDataService.getToShiftTime();
            if (StrUtil.isNotEmpty(toShiftTime)) {
                stringRedisTemplate.opsForValue().set(Constants.TO_SHIFT, toShiftTime, 8L, TimeUnit.HOURS);
            }
        }
    }

    /**
     * 发送交班成功到服务器
     */
    @Scheduled(fixedRate = 2000)
    public void sendShiftDone() {
        if (ControlType.REDIS.getCode().equals(controlType)) {
            String time = stringRedisTemplate.opsForValue().get(Constants.TO_SEND_SHIFT_DONE);
            if (StrUtil.isNotEmpty(time)) {
                boolean shiftDone = petrolDataService.sendShiftDone(time);
                if (shiftDone) {
                    stringRedisTemplate.delete(Constants.TO_SEND_SHIFT_DONE);
                }
            }
        }
    }
}
